package com.ssy.lingxi.platform.template.service.serviceimpl.web;

import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.constant.template.PageTemplateTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberInnerControllerFeign;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberLevelRightCreditControllerFeign;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignIdVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignLrcVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignRegisterQueryVO;
import com.ssy.lingxi.platform.manage.api.feign.inner.AreaControllerFeign;
import com.ssy.lingxi.platform.template.service.constant.*;
import com.ssy.lingxi.platform.template.service.entity.adorn.PageTemplate;
import com.ssy.lingxi.platform.template.service.entity.door.MemberChannel;
import com.ssy.lingxi.platform.template.service.entity.door.Seo;
import com.ssy.lingxi.platform.template.service.model.bo.AreaBO;
import com.ssy.lingxi.platform.template.service.model.bo.MemberBO;
import com.ssy.lingxi.platform.template.service.model.dto.common.MemberIdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.SaveChannelDTO;
import com.ssy.lingxi.platform.template.service.model.vo.web.MemberChannelMainVO;
import com.ssy.lingxi.platform.template.service.repository.MemberChannelRepository;
import com.ssy.lingxi.platform.template.service.repository.PageTemplateRepository;
import com.ssy.lingxi.platform.template.service.repository.SeoRepository;
import com.ssy.lingxi.platform.template.service.service.web.MemberChannelWebService;
import com.ssy.lingxi.product.api.feign.ICommodityFeign;
import com.ssy.lingxi.product.api.model.request.MemberRequest;
import com.ssy.lingxi.product.api.model.response.store.StoreResponse;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * @author fhj
 * @version 2.0.0
 * @menu web - 会员渠道门户 - 业务实现层
 * @date 2020/12/25
 */
@Slf4j
@Service
public class MemberChannelWebServiceImpl implements MemberChannelWebService {

    @Resource
    private PageTemplateRepository pageTemplateRepository;
    @Resource
    private MemberChannelRepository memberChannelRepository;
    @Resource
    private MemberLevelRightCreditControllerFeign memberLevelRightCreditControllerFeign;
    @Resource
    private MemberInnerControllerFeign memberInnerControllerFeign;
    @Resource
    private AreaControllerFeign areaControllerFeign;
    @Resource
    private ICommodityFeign commodityFeign;
    @Resource
    private SeoRepository seoRepository;

    @Override
    @Transactional
    @ApiOperation(value = "保存当前登录会员的渠道门户")
    public Wrapper<Void> saveCurrMemberChannel(SaveChannelDTO dto, UserLoginCacheDTO user) {
        //校验（只有是服务提供者且企业类型是渠道会员或渠道个人会员才能创建渠道, 目前只支持一个会员只能创建一个渠道）
        if (!user.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
            return Wrapper.fail(ResponseCode.PURCHASE_PURCHASE_ROLE_TYPE_MUST_BE_SERVICE_PROVIDER);
        }
        if (!(user.getMemberType().equals(MemberTypeEnum.CHANNEL.getCode()) || user.getMemberType().equals(MemberTypeEnum.CHANNEL_PERSONAL.getCode()))) {
            return Wrapper.fail(ResponseCode.PURCHASE_PURCHASE_ROLE_TYPE_MUST_BE_CHANNEL_MEMBER_OR_CHANNEL_INDIVIDUAL_MEMBER);
        }

        //默认省、市编码都为0（所有/所有）
        List<String> provinceCodes = Stream.of("0").collect(toList());
        List<String> cityCodes = Stream.of("0").collect(toList());
        if (dto.getMemberChannelAreas().stream().noneMatch(a -> a.getProvinceCode().equals("0"))) {
            provinceCodes = dto.getMemberChannelAreas().stream().map(AreaBO::getProvinceCode).collect(Collectors.toList());
            cityCodes = dto.getMemberChannelAreas().stream().filter(a -> !a.getCityCode().equals("0")).map(AreaBO::getCityCode).collect(Collectors.toList());

            List<String> feignCodes = dto.getMemberChannelAreas().stream().filter(a -> a.getCityCode().equals("0")).map(AreaBO::getProvinceCode).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(feignCodes)) {
                Wrapper<List<String>> cityCodesWrapper = areaControllerFeign.findCityCodeByProvinceCode(feignCodes);
                if (cityCodesWrapper.getCode() == ResponseCode.SUCCESS.getCode() && CollectionUtil.isNotEmpty(cityCodesWrapper.getData())) {
                    cityCodes.addAll(cityCodesWrapper.getData());
                }
            }
        }

        //调用会员服务 -> 根据会员ID和角色ID获取平台会员的等级、注册年数、信用积分
        MemberFeignVO memberFeignVO = new MemberFeignVO();
        memberFeignVO.setMemberId(user.getMemberId());
        memberFeignVO.setRoleId(user.getMemberRoleId());
        Wrapper<MemberFeignLrcVO> platformMemberLrcWrapper = memberLevelRightCreditControllerFeign.getPlatformMemberLrc(memberFeignVO);
        if (platformMemberLrcWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用会员服务失败：{}", platformMemberLrcWrapper.getMessage());
            return Wrapper.fail(ResponseCode.SERVICE_MERCHANT_MEMBER_ERROR);
        }
        //调用会员服务 -> 根据会员Id查询会员注册信息
        MemberFeignIdVO memberFeignIdVO = new MemberFeignIdVO();
        memberFeignIdVO.setMemberId(user.getMemberId());
        Wrapper<MemberFeignRegisterQueryVO> memberRegisterInfoWrapper = memberInnerControllerFeign.getMemberRegisterInfo(memberFeignIdVO);
        if (memberRegisterInfoWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用会员服务失败：{}", memberRegisterInfoWrapper.getMessage());
        }

        //保存会员渠道门户
        MemberChannel memberChannel = memberChannelRepository.findByMemberId(user.getMemberId());
        memberChannel = memberChannel != null ? memberChannel : new MemberChannel();
        memberChannel.setMemberId(user.getMemberId());
        memberChannel.setRoleId(user.getMemberRoleId());
        memberChannel.setMemberChannelAreas(dto.getMemberChannelAreas());
        memberChannel.setLogo(dto.getLogo());
        memberChannel.setDescribe(dto.getDescribe());
        memberChannel.setWorkshopPics(dto.getWorkshopPics());
        memberChannel.setHonorPics(dto.getHonorPics());
        memberChannel.setAlbumName(dto.getAlbumName());
        memberChannel.setAlbumUrl(dto.getAlbumUrl());
        memberChannel.setPromotionPic(dto.getPromotionPic());
        memberChannel.setPhone(dto.getPhone());
        memberChannel.setAddress(dto.getAddress());
        memberChannel.setLng(dto.getLng());
        memberChannel.setLat(dto.getLat());
        memberChannel.setAreas(dto.getMemberChannelAreas().stream().map(a -> a.getProvince() + "/" + a.getCity()).collect(Collectors.joining("，")));
        memberChannel.setProvincesCodeList(String.join("，", provinceCodes));
        memberChannel.setCityCodeList(String.join("，", cityCodes));
        memberChannel.setMemberName(user.getCompany());
        memberChannel.setLevelTag(platformMemberLrcWrapper.getData().getLevelTag());
        memberChannel.setRegisterYears(platformMemberLrcWrapper.getData().getRegisterYears());
        memberChannel.setCreditPoint(platformMemberLrcWrapper.getData().getCreditPoint());
        memberChannel.setRegisteredCapital(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisteredCapital() : null);
        memberChannel.setEstablishmentDate(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getEstablishmentDate() : null);
        memberChannel.setBusinessLicence(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getBusinessLicence() : null);
        memberChannel.setRegisterArea(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisterArea() : null);
        memberChannel.setRegisterAddress(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisterAddress() : null);
        if (StringUtils.isBlank(memberChannel.getInviteCode())) {
            generateInviteCode(memberChannel);
        }
        memberChannelRepository.saveAndFlush(memberChannel);

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "获取当前登录会员的渠道门户")
    public Wrapper<MemberChannel> findCurrMemberChannel(UserLoginCacheDTO user) {
        return Wrapper.success(memberChannelRepository.findByMemberId(user.getMemberId()));
    }

    @Override
    @ApiOperation(value = "渠道门户主页")
    public Wrapper<MemberChannelMainVO> memberChannelMain(MemberIdDTO dto) {
        //根据会员ID获取渠道
        MemberChannel memberChannel = memberChannelRepository.findByMemberId(dto.getMemberId());
        if (memberChannel == null) {
            return Wrapper.fail(ResponseCode.PT_NOT_FOUND_MEMBER_CHANNEL);
        }

        //拷贝
        MemberChannelMainVO memberChannelMainVO = new MemberChannelMainVO();
        BeanUtils.copyProperties(memberChannel, memberChannelMainVO);

        //获取当前会员正在使用中的渠道、渠道自有模板，封装模板ID和前端关联模板文件名称
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndShelf(
                PageTemplateEnvironmentEnum.WEB.getCode(),
                PageTemplateTypeEnum.CHANNEL.getCode(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<PageTemplate> usePageTemplateList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseChannelTemplate()) &&
                            a.getUseChannelTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(memberChannel.getMemberId())
                            )
            ).collect(Collectors.toList());

            //渠道模板和渠道自有模板
            if (CollectionUtil.isNotEmpty(usePageTemplateList)) {
                List<PageTemplate> channelShopTemplateList = usePageTemplateList.stream().filter(a -> a.getShopType().equals(PageTemplateShopTypeEnum.CHANNEL.getCode())).collect(toList());
                if (CollectionUtil.isNotEmpty(channelShopTemplateList)) {
                    if (channelShopTemplateList.size() > 1) {
                        log.error("正在使用的渠道模板出现多个【检查原因】");
                    }
                    memberChannelMainVO.setChannelShopTemplateId(channelShopTemplateList.get(0).getId());
                    memberChannelMainVO.setChannelShopTemplateFileName(channelShopTemplateList.get(0).getFileName());
                    //设置用户自己的mro是否开启
                    List<MemberBO> useChannelTemplate = channelShopTemplateList.get(0).getUseChannelTemplate().stream().filter(b -> dto.getMemberId().equals(b.getMemberId())).collect(toList());
                    if (useChannelTemplate.size() > 0) {
                        memberChannelMainVO.setChannelShopOpenMro(useChannelTemplate.get(0).getOpenMro());
                    }

                }

                List<PageTemplate> channelOwnShopTemplateList = usePageTemplateList.stream().filter(a -> a.getShopType().equals(PageTemplateShopTypeEnum.CHANNEL_SELF.getCode())).collect(toList());
                if (CollectionUtil.isNotEmpty(channelOwnShopTemplateList)) {
                    if (channelOwnShopTemplateList.size() > 1) {
                        log.error("正在使用的渠道自有模板出现多个【检查原因】");
                    }
                    memberChannelMainVO.setChannelOwnShopTemplateId(channelOwnShopTemplateList.get(0).getId());
                    memberChannelMainVO.setChannelOwnShopTemplateFileName(channelOwnShopTemplateList.get(0).getFileName());
                    //设置用户自己的mro是否开启
                    List<MemberBO> useChannelTemplate = channelOwnShopTemplateList.get(0).getUseChannelTemplate().stream().filter(b -> dto.getMemberId().equals(b.getMemberId())).collect(toList());
                    if (useChannelTemplate.size() > 0) {
                        memberChannelMainVO.setChannelOwnShopOpenMro(useChannelTemplate.get(0).getOpenMro());
                    }


                }
            }
        }

        //调用商品服务 -> 根据会员ID和角色ID集合获取渠道的主营分类
        MemberRequest memberRequest = new MemberRequest();
        memberRequest.setMemberId(memberChannelMainVO.getMemberId());
        memberRequest.setMemberRoleId(memberChannelMainVO.getRoleId());
        Map<String, StoreResponse> map = commodityFeign.getCommodityAndCategoryByMemberIdAndMemberRoleId(
                Stream.of(memberRequest).collect(toList())
        );
        if (CollectionUtil.isNotEmpty(map) && map.get(memberChannelMainVO.getMemberId() + "-" + memberChannelMainVO.getRoleId()) != null) {
            memberChannelMainVO.setCustomerCategoryName(map.get(memberChannelMainVO.getMemberId() + "-" + memberChannelMainVO.getRoleId()).getCustomerCategoryName());
        }

        //获取渠道SEO
        List<Seo> seoList = seoRepository.findAllByDoorTypeAndDoorIdAndStatus(
                SeoDoorTypeEnum.CHANNEL.getCode(),
                memberChannel.getId(),
                CommonBooleanEnum.YES.getCode()
        );
        //封装渠道SEO(首页、关于我们)
        if (CollectionUtil.isNotEmpty(seoList)) {
            Seo homePage = seoList.stream().filter(a -> a.getType().equals(SeoTypeEnum.HOME_PAGE.getCode())).findFirst().orElse(null);
            Seo aboutUs = seoList.stream().filter(a -> a.getType().equals(SeoTypeEnum.ABOUT_US.getCode())).findFirst().orElse(null);
            memberChannelMainVO.setHomePage(homePage);
            memberChannelMainVO.setAboutUs(aboutUs);
        }

        //默认先满星
        if (memberChannelMainVO.getAvgTradeCommentStar() == null || memberChannelMainVO.getAvgTradeCommentStar() == 0) {
            memberChannelMainVO.setAvgTradeCommentStar(5);
        }

        return Wrapper.success(memberChannelMainVO);
    }

    @Override
    @ApiOperation(value = "所有")
    public Wrapper<List<MemberChannel>> all() {
        return Wrapper.success(memberChannelRepository.findAll(Sort.by("createTime").descending()));
    }

    /**
     * 生成随机邀请码（六位）
     */
    private void generateInviteCode(MemberChannel memberChannel) {
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append(str.charAt(new Random().nextInt(str.length())));
        }

        if (memberChannelRepository.existsByInviteCode(code.toString())) {
            generateInviteCode(memberChannel);
        } else {
            memberChannel.setInviteCode(code.toString());
        }
    }
}
